import CryptoJS from "crypto-js";
function getUuid() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

function hashFile(file) {
  function hashFileInternal(file, alog) {
    alog = alog || CryptoJS.algo.MD5.create();
    const chunkSize = 20 * 1024 * 1024;
    let promise = Promise.resolve();
    for (let index = 0; index < file.size; index += chunkSize) {
      promise = promise.then(() =>
        hashBlob(file.slice(index, index + chunkSize))
      );
    }

    /**
     * 更新文件块的hash值
     */
    function hashBlob(blob) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = ({ target }) => {
          const wordArray = CryptoJS.lib.WordArray.create(target.result);
          // 增量更新计算结果
          alog.update(wordArray);
          resolve();
        };
        reader.readAsArrayBuffer(blob);
      });
    }
    // 使用promise返回最终的计算结果
    return promise.then(() => CryptoJS.enc.Hex.stringify(alog.finalize()));
  }
  // 同时计算文件的sha256和md5,并使用promise返回
  //   return Promise.all([hashFileInternal(file, CryptoJS.algo.SHA256.create()),
  //     hashFileInternal(file, CryptoJS.algo.MD5.create())])
  // .then(([sha256, md5]) => ({
  // sha256,
  // md5
  // }))
  return Promise.all([hashFileInternal(file)]).then(([md5]) => ({
    md5,
  }));
}

function getFileSignature(file, fileType, md5) {
  return new Promise(async (resolve, reject) => {
    const signatureSecurityKey = "F7FC0D74AA8CE8C4";
    const data = {
      "ifutian-timestamp": Date.now(),
      "ifutian-nonce": getUuid(),
      "ifutian-signature": "",
      'md5': ''
    };
    data['md5'] = md5 ||  (await hashFile(file)).md5;
    if(data['md5']) {
      const srt = `${data["ifutian-timestamp"]}${data['md5']}${fileType}${signatureSecurityKey}${data["ifutian-nonce"]}${data["ifutian-timestamp"]}`;
      data["ifutian-signature"] = CryptoJS.SHA256(srt.toUpperCase()).toString();
      resolve(data);
    }else {
      reject(null)
    }
  });
}

// 获取多个文件md5
async  function getFilesMd5(files) {
  let md5= null
  for (const file of files) {
    const r = await hashFile(file);
    md5 = md5 ? ( md5+ r.md5) :  r.md5 
  }
  return md5
}

export {
  getFileSignature,
  hashFile,
  getFilesMd5
}

